#include "server.h"

client *head;

int main()
{
	int sock = CreateTcpServer(8888);
	pthread_t tidupload;
	pthread_create(&tidupload,NULL,down_upload_server,NULL);

	head = (client *)malloc(sizeof(client));
	head->num = 0;
	head->csock = sock;
	strcpy(head->name,"server-lc");
	strcpy(head->ip,"0.0.0.0");
	head->port = 8888;
	head->next = NULL;

	struct epoll_event tep;
	struct epoll_event ep[1024];
	char buf[1024];
	char send_buf[1024];
	int ret;

	int efd = epoll_create(1024);
	if(efd == -1)
	{
		close(sock);
		return 0;
	}
	
	int nready;
	int connfd;
	unsigned int clilen;
	struct sockaddr_in cliaddr;
	tep.events = EPOLLIN;
	tep.data.fd = sock;
	epoll_ctl(efd,EPOLL_CTL_ADD,sock,&tep);
	tep.events = EPOLLIN;
	tep.data.fd = 0;
	epoll_ctl(efd,EPOLL_CTL_ADD,0,&tep);

	while((nready = epoll_wait(efd,ep,1024,-1)) >= 0)
	{
		for (int i = 0; i < nready; i++)
		{
			memset(send_buf,0,sizeof(send_buf));
			memset(buf,0,sizeof(buf));
			if(!(ep[i].events & EPOLLIN))
				continue;
			if(ep[i].data.fd == sock)
			{
				clilen = sizeof(cliaddr);
				connfd = accept(sock,(struct sockaddr *)&cliaddr,&clilen);
				tep.events = EPOLLIN;
				tep.data.fd = connfd;
				epoll_ctl(efd,EPOLL_CTL_ADD,connfd,&tep);

				client *p,*addp;
				p = head;
				while(p->next)
					p = p->next;
				addp = (client *)malloc(sizeof(client));
				addp->num = p->num+1;
				addp->csock = connfd;
				sprintf(addp->name,"client-%d",addp->num);
				inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,addp->ip,sizeof(addp->ip));
				addp->port = ntohs(cliaddr.sin_port);
				addp->next = NULL;
				p->next = addp;
				sprintf(send_buf,"[%s][%s][%d] is login",addp->name,addp->ip,addp->port);
				p = head->next;
				while(p)
				{
					send(p->csock,send_buf,strlen(send_buf),0);
					p = p->next;
				}
				printf("%s\n",send_buf);

				
			}
			else if(ep[i].data.fd == 0)
			{
				fgets(buf,20,stdin);
				if(!strcmp(buf,"quit\n"))
				{
					client *p,*tp;
					p = head->next;
					while(p)
					{
						tp = p;
						send(tp->csock,"server quit",11,0);
						close(tp->csock);
						free(tp);
						p = p->next;
					}
					close(sock);
					return 0;
				}
			}
			else  
			{
				int csock = ep[i].data.fd;
				ret = recv(csock,buf,sizeof(buf),0);
				if(ret <= 0)
				{
					epoll_ctl(efd,EPOLL_CTL_DEL,csock,NULL);
					client *p,*tp;
					tp = head;
					p = head->next;
					while(p)
					{
						if(p->csock == csock)
							break;
						tp = p;
						p = p->next;
					}
					close(p->csock);
					tp->next = p->next;
					sprintf(send_buf,"[%s][%s][%d] is quit",p->name,p->ip,p->port);
					free(p);

					p = head->next;
					while(p)
					{
						send(p->csock,send_buf,strlen(send_buf),0);
						p = p->next;
					}
					printf("%s\n",send_buf);


				}
				else
				{
					if(!strcmp(buf,"quit"))
					{
						epoll_ctl(efd,EPOLL_CTL_DEL,connfd,&tep);
						client *p,*tp;
						tp = head;
						p = head->next;
						while(p)
						{
							if(p->csock == csock)
								break;
							tp = p;
							p = p->next;
						}
						close(p->csock);
						tp->next = p->next;
						sprintf(send_buf,"[%s][%s][%d] is quit",p->name,p->ip,p->port);
						free(p);
						
						p = head->next;
						while(p)
						{
							send(p->csock,send_buf,strlen(send_buf),0);
							p = p->next;
						}
						printf("%s\n",send_buf);
						continue;

					}
					else if(!strncmp(buf,"changename",10))
					{
						client *p;
						p = head->next;
						while(p)
						{
							if(p->csock == csock)
								break;
							p = p->next;
						}
						sprintf(send_buf,"[%s] change name to [%s]",p->name,buf+11);
						strcpy(p->name,buf+11);

						p = head->next;
						while(p)
						{
							send(p->csock,send_buf,strlen(send_buf),0);
							p = p->next;
						}
						printf("%s\n",send_buf);
					}
					else if(!strcmp(buf,"list"))
					{
						DIR *dir = opendir(".");
						struct dirent *a;
						char filename[100];
						char listfile[1024];
						memset(listfile,0,sizeof(listfile));
						while ((a = readdir(dir)))
						{
							if(strcmp(a->d_name,".") == 0 || strcmp(a->d_name,"..") == 0 )
								continue;
							memset(filename,0,sizeof(filename));
							strcpy(filename,a->d_name);
							strcat(filename," ");
							strcat(listfile,filename);		
						}
						closedir(dir);

						send(csock,listfile,strlen(listfile),0);

					}
					/*else if(!strncmp(buf,"download",8))
					{
						char buff[1024];
						sprintf(buff,"%d %s",csock,buf);
						pthread_t tid;
						pthread_create(&tid,NULL,send_file,buff);
					}*/
					else
					{	
						client *p;
						p = head->next;
						while(p)
							{
								if(p->csock == csock)
									break;
								p = p->next;
							}
						sprintf(send_buf,"[%s][%s][%d]:%s",p->name,p->ip,p->port,buf);
						
						p = head->next;
						while(p)
						{
							send(p->csock,send_buf,strlen(send_buf),0);
							p = p->next;
						}
						printf("%s\n",send_buf);
					}
				}
			}
		}

	}
}



